package cc.shacocloud.kotlin.tools

import cc.shacocloud.kotlin.tools.amqp.AmqpProperties
import cc.shacocloud.kotlin.tools.amqp.AmqpTemplate
import cc.shacocloud.kotlin.tools.csv.CsvParser
import cc.shacocloud.kotlin.tools.csv.CsvReadConfig
import cc.shacocloud.kotlin.tools.http.Http
import cc.shacocloud.kotlin.tools.jdbc.JdbcDataSource
import cc.shacocloud.kotlin.tools.jdbc.JdbcProperties
import cc.shacocloud.kotlin.tools.jdbc.JdbcTemplate
import java.io.*
import java.nio.charset.Charset

/**
 * jdbc 一次性链接和事务连接操作
 * @author 思追(shaco)
 */
fun <R> useTransactions(properties: JdbcProperties, handler: JdbcTemplate.() -> R): R {
    properties.apply {
        maximumPoolSize = 1
        minimumIdle = 1
    }

    return JdbcDataSource(properties).use { it.useTransactions(handler) }
}

/**
 * 使用数据源
 * @author 思追(shaco)
 */
fun <R> useDataSource(properties: JdbcProperties, handler: JdbcDataSource.() -> R): R {
    return JdbcDataSource(properties).use { it.run(handler) }
}

/**
 * http 函数
 */
fun <T> http(handler: Http.() -> T): T {
    return Http.run(handler)
}

/**
 * 输入流转 csv 解析器
 */
fun <R> InputStream.csvParser(
    charset: Charset = Charsets.UTF_8,
    config: CsvReadConfig = CsvReadConfig.DEFAULT,
    handler: (CsvParser) -> R
): R {
    return CsvParser(InputStreamReader(this, charset), config).use { handler(it) }
}

/**
 * 读取器转 csv 解析器
 */
fun <R> Reader.csvParser(
    config: CsvReadConfig = CsvReadConfig.DEFAULT,
    handler: (CsvParser) -> R
): R {
    return CsvParser(this, config).use { handler(it) }
}

/**
 * 读取器转 csv 解析器
 */
fun <R> File.csvParser(
    charset: Charset = Charsets.UTF_8,
    config: CsvReadConfig = CsvReadConfig.DEFAULT,
    handler: (CsvParser) -> R
): R {
    return CsvParser(InputStreamReader(FileInputStream(this), charset), config).use { handler(it) }
}

/**
 * 使用 amqp 模板
 */
fun <R> useAmqpTemplate(
    properties: AmqpProperties,
    handler: AmqpTemplate.() -> R
): R {
    val connectionFactory = properties.getConnectionFactory()
    return connectionFactory.newConnection().use { conn -> AmqpTemplate(conn).handler() }
}